package edu.xmut.kakamusic.activity.service;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.util.Log;

import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import edu.xmut.kakamusic.bean.entity.Music;
import edu.xmut.kakamusic.utils.Constants;
import edu.xmut.kakamusic.utils.NetworkUtils;
import edu.xmut.kakamusic.utils.ToastUtils;
import lombok.Getter;
import lombok.Setter;

public class MusicPlayerService extends Service {

    private static final String TAG = "MusicPlayerService";

    @Getter
    private static MusicPlayerService instance;

    /**
     * 播放队列
     */
    @Getter
    public List<Music> playQueue = new ArrayList<>();

    /**
     * 播放器
     */
    private MediaPlayer player;

    /**
     * 本地广播管理器
     */
    private LocalBroadcastManager localBroadcastManager;

    /**
     * 本地广播接收器
     */
    private LocalMusicReceiver localReceiver;

    private static int serviceStartId;

    /**
     * 是否正在播放
     */
    private static boolean isMusicPlaying = false;

    /**
     * 是否暂停
     */
    private static boolean isMusicPaused = false;

    /**
     * 播放位置
     */
    private int playingPosition = -1;

    /**
     * 正在播放的音乐
     */
    private static Music playingMusic = null;

    // 获取当前播放模式
    // 设置播放模式
    // 播放模式，默认顺序播放
    @Getter
    @Setter
    private static int playMode = Constants.PLAY_MODE_SEQUENCE;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        //初始化广播
        initReceiver();
        //初始化音乐播放服务
        initMediaPlayer();
    }

    /**
     * 初始化音乐播放服务
     */
    private void initMediaPlayer() {
        player = new MediaPlayer();
        // 日志回调
        player.setOnInfoListener((mp, what, extra) -> {
            Log.d(TAG, "onInfo= what:" + what + " extra:" + extra);
            return true;
        });
        // 播放错误回调
        player.setOnErrorListener((mp, what, extra) -> {
            Log.d(TAG, "onError= what:" + what + " extra:" + extra);
            return true;
        });
        // 修改播放完成回调
        player.setOnCompletionListener(mp -> {
            isMusicPlaying = false;
            Log.d(TAG, "onCompletion 播放完成");
            switch (playMode) {
                case Constants.PLAY_MODE_SINGLE:
                    // 单曲循环，重新播放当前歌曲
                    playCurrentAndNext();
                    break;
                case Constants.PLAY_MODE_RANDOM:
                    // 随机播放
                    playRandom();
                    break;
                case Constants.PLAY_MODE_SEQUENCE:
                    // 顺序播放
                    playNext();
                    break;
            }
        });
        // 拖动进度条完成回调
        player.setOnSeekCompleteListener(mp -> Log.d(TAG, "onSeekComplete"));
    }

    private void initReceiver() {
        // 获取localBroadcastManager实例
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        // 实例化广播接收器
        localReceiver = new LocalMusicReceiver();
        // 注册意图，并添加若干意图过滤器
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Constants.PLAY);
        intentFilter.addAction(Constants.NEXT);
        intentFilter.addAction(Constants.PREVIOUS);
        intentFilter.addAction(Constants.STOP);
        intentFilter.addAction(Constants.PAUSE);
        intentFilter.addAction(Constants.GET_MUSIC_DATA);
        // 注册广播接收器
        localBroadcastManager.registerReceiver(localReceiver, intentFilter);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        serviceStartId = startId;
        String action = intent.getAction();
        if (Objects.nonNull(intent) && Objects.nonNull(action)) {
            handleCommandIntent(intent);
        }
        return START_STICKY;
    }

    public static boolean isRunning() {
        return serviceStartId != 0;
    }


    @Override
    public void onDestroy() {
        // 销毁播放器
        if (player != null) {
            player.stop();
            player.release();
        }
        // 解注册广播
        if (Objects.nonNull(localBroadcastManager)) {
            localBroadcastManager.unregisterReceiver(localReceiver);
        }
        // 标注为关闭
        serviceStartId = 0;
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    /**
     * 是否正在播放音乐
     */
    public static boolean isPlaying() {
        return isMusicPlaying;
    }

    /**
     * 判断是否暂停
     */
    public static boolean isMusicPaused() {
        return Objects.nonNull(playingMusic) && isMusicPaused;
    }

    public int getMusicQueueSize() {
        return playQueue.size();
    }


    /**
     * 播放音乐
     */
    private void playMusic(Music music) {
        // 判断是否是暂停回来
        if (isMusicPaused()) {
            player.start();
            isMusicPaused = false;
            isMusicPlaying = true;
            return;
        }
        // 如果是第一次播放
        if (Objects.isNull(music)) {
            ToastUtils.show(this, "音乐为空");
            return;
        }
        if (Objects.nonNull(player) && isPlaying()) {
            player.stop();
            player.reset();
        }
        // 如果播放列表为空，则添加当前音乐
        if (playQueue.isEmpty()) {
            playingPosition = 0;
            playQueue.add(music);
        } else if (playingPosition < getMusicQueueSize()) {
            // 如果当前播放位置在列表中的中间，则插入到当前播放位置的下一首中
            playQueue.add(playingPosition, music);
        } else if (playingPosition >= getMusicQueueSize()) {
            // 如果播放列表中不存在该音乐，则添加到播放列表末尾
            playQueue.add(music);
        }
        playingMusic = music;
        // 播放
        playCurrentAndNext();
    }

    public void pauseMusic() {
        if (isPlaying()) {
            player.pause();
            isMusicPlaying = false;
            isMusicPaused = true;
        }
    }


    /**
     * 获取音乐播放器状态
     */
    public static String getMediaPlayerState() {
        if (isPlaying()) {
            return Constants.PLAYING_STATUS;
        } else if (isMusicPaused()) {
            return Constants.PAUSE_STATUS;
        }
        return Constants.STOPPED_STATUS;
    }

    /**
     * 播放当前歌曲
     */
    private void playCurrentAndNext() {
        if (!NetworkUtils.isNetworkAvailable(this)) {
            ToastUtils.show(this, "网络不可用，请检查网络连接");
            return;
        }
        //更新播放播放状态
        isMusicPlaying = false;
        // 开始播放音乐
        try {
            player.setDataSource(playingMusic.getUrl());
            // 判断是否正在播放中
            if (isMusicPlaying) {
                player.stop();
            }
            // 异步准备播放，并且设置准备就绪，播放音乐
            player.prepareAsync();
            player.setOnPreparedListener(mp -> {
                player.start();
                isMusicPlaying = true;
                // 发送广播
                Intent intent = new Intent(Constants.MUSIC_START_PLAY_SERVICE);
                intent.putExtra(Constants.MUSIC_DATA, playingMusic);
                localBroadcastManager.sendBroadcast(intent);
            });
        } catch (Exception exception) {
            Log.d(TAG, "playCurrentAndNext: " + exception);
            Log.d(TAG, "playCurrentAndNext: " + exception.getMessage());
            ToastUtils.show(this, "播放失败，请检查音乐地址");
        }
    }

    class LocalMusicReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            // 处理广播群发的意图
            handleCommandIntent(intent);
        }
    }

    /**
     * Intent意图处理
     */
    private void handleCommandIntent(Intent intent) {
        String action = intent.getAction();
        if (Objects.isNull(action)) {
            return;
        }
        Log.d(TAG, "handleCommandIntent: " + "接收到意图: " + action);
        switch (Objects.requireNonNull(action)) {
            case Constants.PLAY:
                Music music = (Music) intent.getSerializableExtra(Constants.MUSIC_DATA);
                Log.d(TAG, "handleCommandIntent: " + music);
                playMusic(music);
                break;
            case Constants.PAUSE:
                pauseMusic();
                break;
            case Constants.PREVIOUS:
                playPrevious();
                break;
            case Constants.NEXT:
                playNext();
                break;
            case Constants.GET_MUSIC_DATA:
                sendMusicInfo();
                break;
            default:
                ToastUtils.show(this, "未知操作");
                break;
        }
    }

    private void sendMusicInfo() {
        Intent intent = new Intent(Constants.MUSIC_DATA);
        intent.putExtra(Constants.MUSIC_DATA, playingMusic);
        localBroadcastManager.sendBroadcast(intent);
    }

    // 添加播放上一首方法
    private void playPrevious() {
        if (playQueue.isEmpty()) {
            ToastUtils.show(this, "播放列表为空");
            return;
        }

        playingPosition--;
        if (playingPosition < 0) {
            playingPosition = playQueue.size() - 1;
        }

        playingMusic = playQueue.get(playingPosition);
        if (Objects.nonNull(player)) {
            player.reset();
            playCurrentAndNext();
        }
    }

    // 添加播放下一首方法
    private void playNext() {
        if (playQueue.isEmpty()) {
            ToastUtils.show(this, "播放列表为空");
            return;
        }
        // 如果是随机播放模式
        if (Objects.equals(Constants.PLAY_MODE_RANDOM, playMode)) {
            playRandom();
            return;
        }
        playingPosition++;
        if (playingPosition >= playQueue.size()) {
            playingPosition = 0;
        }
        playingMusic = playQueue.get(playingPosition);
        if (Objects.nonNull(player)) {
            player.reset();
            playCurrentAndNext();
        }
    }

    // 添加随机播放方法
    private void playRandom() {
        if (playQueue.isEmpty()) {
            ToastUtils.show(this, "播放列表为空");
            return;
        }

        // 生成随机索引，避免重复播放当前歌曲
        int newPosition;
        if (playQueue.size() > 1) {
            do {
                newPosition = (int) (Math.random() * playQueue.size());
            } while (newPosition == playingPosition);
        } else {
            newPosition = 0;
        }

        playingPosition = newPosition;
        playingMusic = playQueue.get(playingPosition);
        if (Objects.nonNull(player)) {
            player.reset();
            playCurrentAndNext();
        }
    }

    /**
     * 获取当前播放位置
     */
    public int getCurrentPosition() {
        if (player != null) {
            return player.getCurrentPosition();
        }
        return 0;
    }

    /**
     * 获取音乐总时长
     */
    public int getDuration() {
        if (player != null) {
            return player.getDuration();
        }
        return 0;
    }

    /**
     * 跳转到指定位置
     */
    public void seekTo(int position) {
        if (player != null) {
            player.seekTo(position);
        }
    }

    public void playAtPosition(int position) {
        if (position >= 0 && position < playQueue.size()) {
            playingPosition = position;
            playingMusic = playQueue.get(position);
            if (Objects.nonNull(player)) {
                player.reset();
                playCurrentAndNext();
            }
        }
    }

    public void removeFromQueue(int position) {
        if (position >= 0 && position < playQueue.size()) {
            playQueue.remove(position);
            if (position < playingPosition) {
                playingPosition--;
            } else if (position == playingPosition) {
                if (position >= playQueue.size()) {
                    playingPosition = 0;
                }
                if (!playQueue.isEmpty()) {
                    playingMusic = playQueue.get(playingPosition);
                    if (Objects.nonNull(player)) {
                        player.reset();
                        playCurrentAndNext();
                    }
                }
            }
        }
    }
}

